Vite's HMR API provides hot.accept() to handle module updates, hot.dispose() to clean up before updates, and hot.invalidate() to force a full page reload when needed
Vite's HMR API is exposed through the import.meta.hot object, providing developers with fine-grained control over how modules respond to updates. These APIs are only available during development and are automatically stripped from production builds. The three core methods—accept(), dispose(), and invalidate()—form the foundation of custom HMR handling, enabling modules to preserve state, perform cleanup, and gracefully handle updates that can't be hot-applied .
The accept() method tells Vite that a module can handle updates to itself or its dependencies. When a module accepts updates, Vite will apply changes without reloading the page. This is essential for preserving application state during development. Framework integrations like @vitejs/plugin-vue or @vitejs/plugin-react automatically inject appropriate accept handlers for components, but custom modules may need to implement their own .
The dispose() method registers a callback that runs before a module is updated or unmounted. This is crucial for cleaning up resources like event listeners, intervals, or DOM elements that were created by the module. Without proper disposal, the old module's resources would leak, potentially causing memory issues or duplicate event handlers after hot updates .
The invalidate() method forces a full page reload when a module cannot safely handle a hot update. This is useful when a module detects that its internal state or dependencies have changed in ways that can't be reconciled with HMR. Calling invalidate() also accepts an optional error message that will be displayed in the browser console .
Initial load: Module registers accept/dispose handlers if it wants HMR support .
File change detected: Vite server identifies changed file and affected modules .
Update propagation: Server sends WebSocket message to client with affected module paths .
Dispose phase: Client executes dispose handlers for modules being updated, allowing cleanup .
Fetch new modules: Client dynamically imports updated modules with cache-busting timestamps .
Accept phase: Client executes accept handlers with new module exports .
Fallback: If no accept handler exists for the updated module, Vite triggers full page reload .
Most developers never need to use the raw HMR API directly. Framework plugins like @vitejs/plugin-vue and @vitejs/plugin-react automatically inject appropriate HMR handlers for components . They use the API under the hood to preserve component state and enable fast refresh experiences. The raw API becomes valuable for library authors or when building custom non-framework applications that need granular update control .